from pandas import DataFrame
from common.analyzer_common.search import DISearch
from common.analyzer_common.operator import OP


class PanelSearch(DISearch):
    """图表数据
    1. 搜索获取图表数据
    2. 根据option转换
    """
    @classmethod
    def _alias(cls, df, alias):
        return df.rename(columns=alias)

    @classmethod
    def _conversion(cls, df, conversions):
        """数值转换 +-*/"""
        for k, v in conversions.items():
            if k not in df.columns:
                continue
            op, number = getattr(OP, v['operator']), v['number']
            df[k] = df[k].apply(op, args=(number, ))
        return df

    @classmethod
    def _round(cls, df, rounds):
        """数值转换 +-*/"""
        df = df.round(rounds)
        return df

    @classmethod
    def visualize_dataframe(cls, result, configure):
        """
        数据转换
        重命名
        保留小数等
        """
        if not (configure.get('group_options') or configure.get('metric_options')):  # 事件计数 不统计分组指标
            df = DataFrame([item['_source'] for item in result['hits']['hits']])
        else:
            values = list(cls.flattern_aggs(result['aggregations']))
            df = DataFrame(data=values)

        alias = {k: v.get('alias') for k, v in configure.get('option', {}).items() if v.get('alias')}
        conversions = {k: v.get('conversion') for k, v in configure.get('option', {}).items() if v.get('conversion')}
        rounds = {k: v.get('round') for k, v in configure.get('option', {}).items() if v.get('round')}

        df = cls._conversion(df, conversions)
        df = cls._round(df, rounds)
        df = cls._alias(df, alias)
        return df

    @classmethod
    def visualize_data(cls, search, configure):
        """可视化 图表数据
        1. 数据查询条件构建
        2. 搜索数据
        3. 数据格式化为图表形式数据
        """
        aggs = cls.build_aggs(configure)
        if aggs:
            search['condition']['aggs'] = aggs
        resp = cls.search(search=search)

        df = cls.visualize_dataframe(resp, configure)
        return df.to_dict(orient='list')


if __name__ == '__main__':
    from package.connector.elastic_db import es_db
    es_db.init(hosts='http://192.168.101.80:9200')

    r1 = PanelSearch.visualize_data(search={'scope': '', 'condition': {'query': {'match_all': {}}, 'size': 0}}, 
                    
                             configure={
                                 "group_options": {
                                     'meta': {'type': 'composite', 'size': 1000},
                                     'groups': [
                                         {'name_or_agg': 'terms', 'field': '_host'},
                                         {'name_or_agg': 'terms', 'field': '_datamodel'},
                                        #  {'name_or_agg': 'terms', 'field': 'level'}
                                         ],
                                     "metrics": [
                                        {'name_or_agg': 'value_count', 'field': '_sourceid'},
                                        {'name_or_agg': 'cardinality', 'field': '_sourcename'},
                                        {'name_or_agg': 'percentiles', 'field': '_time', 'percents': [75.5, 88.3]}
                                    ]
                                         },
                                 "metric_options": [
                                    #  {'name_or_agg': 'value_count', 'field': '_datamodel'}
                                    ],
                                 "option": {'terms__host': {'alias': '主机'}, 
                                            'value_count__sourceid': {
                                                'alias': '数据源ID计数',
                                                'round': 2,
                                                'conversion': {'operator': 'add', 'number': 10}
                                                }, 
                                            'cardinality__sourcename': {
                                                'alias': '数据源去重计数',
                                                'round': 3,
                                                'conversion': {'operator': 'div', 'number': 3}
                                                }}
                                 }
                             )

    print(r1)


    r1 = PanelSearch.visualize_data(search={'scope': '', 'condition': {'query': {'match_all': {}}, 'size': 0}}, 
                    
                             configure={
                
                                 }
                             )

    print(r1)